/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#ifndef __FRACTAL_GENERATOR_H__
#define __FRACTAL_GENERATOR_H__

#include "MathUtil.h"

namespace PQEngine
{
	enum FractalGeneratorType
	{
		FTG_MID_DISPLACEMENT,
	};

	class FractalGeneratorImpl
	{
	public:
		virtual void generate(float* data, int size, int seedValue, float heightScale, float h)=0;
	};

	class MidDisplacementGenerator
		: public FractalGeneratorImpl
	{
	public:
		float getSquareMeanValue(int i,int j,int stride,int size,float *data);
		float getDiamondMeanValue(int i, int j, int stride,int size, int subSize, float *data);

		void generate(float* data, int size, int seedValue, float heightScale, float h);
	};

	class FractalGenerator
	{
	public:
		FractalGenerator()
			: _impl(0), _data(0),_type(FTG_MID_DISPLACEMENT)
		{
		}

		static FractalGenerator& getSingleton()
		{
			static FractalGenerator inst;
			return inst;
		}

		void generate(int size, int seedValue, float heightScale, float h);

		float get(int i,int j);

		float* getData()
		{
			return _data;
		}

		/*Clear data.
		*/
		void clear()
		{
			if(_data){
				delete _data;
				_data=0;
			}
		}
	private:
		float* _data;
		int _size;
		int _seg;
		int _capacity;
		float _heightScale;

		FractalGeneratorImpl* _impl;
		FractalGeneratorType _type;
	};

}

#define SFractalTerrainGenerator PQEngine::FractalGenerator::getSingleton()

#endif
